/* Copyright (c) 2008 Google Inc.
*  Copyright (c) 2009 Pierre Henri Kuate.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace org.opensocial.data
{
    /// <summary> An object representing a person in an OpenSocial environment; extends
    /// OpenSocialObject class by adding convenience methods for easily
    /// accessing special fields unique to instances of this class.
    /// </summary>
    /// <author>  Jason Cooper
    /// </author>
    public class Person : OpenSocialObject
    {
        /// <summary> Retrieves the OpenSocial ID associated with the instance. Returns an
        /// empty string if no ID has been set.
        /// </summary>
        public string Id
        {
            get { return getStringValue("id"); }
        }

        /// <summary> Retrieves the display name (typically given name followed by family name)
        /// associated with the instance. Returns an empty string if no name has been set.
        /// </summary>
        public string DisplayName
        {
            get
            {
                OpenSocialField displayNameField = getField("displayName");
                OpenSocialField nicknameField = getField("nickname");
                OpenSocialField nameField = getField("name");
                var name = new System.Text.StringBuilder();

                if (displayNameField != null)
                    name.Append(displayNameField.StringValue);
                else if (nicknameField != null)
                    name.Append(nicknameField.StringValue);
                else if (nameField != null)
                {
                    if (nameField.IsComplex)
                    {
                        OpenSocialObject nameObject = nameField.Value;

                        if (nameObject.hasField("givenName"))
                        {
                            name.Append(nameObject.getField("givenName").StringValue);
                        }

                        if (nameObject.hasField("givenName") && nameObject.hasField("familyName"))
                        {
                            name.Append(" ");
                        }

                        if (nameObject.hasField("familyName"))
                        {
                            name.Append(nameObject.getField("familyName").StringValue);
                        }
                    }
                    else
                    {
                        name.Append(nameField.StringValue);
                    }
                }
                //else
                //    name.Append("Unknown Person"); // TODO: Should throw an exception?

                return name.ToString();
            }
        }

        public string ProfileUrl
        {
            get { return getStringValue("profileUrl"); }
        }

        public string ThumbnailUrl
        {
            get { return getStringValue("thumbnailUrl"); }
        }

        public bool? IsOwner
        {
            get { return getBoolValue("isOwner"); }
        }

        public bool? IsViewer
        {
            get { return getBoolValue("isViewer"); }
        }

        public bool? HasApp
        {
            get { return getBoolValue("hasApp"); }
        }

        public Address CurrentLocation
        {
            get { return singleOrDefaultObjectOfCollection<Address>("currentLocation"); }
        }

        public System.Collections.Generic.IList<Address> Addresses
        {
            get { return getObjects<Address>("addresses"); }
        }

        public System.DateTime? Updated
        {
            get { return getDateTimeValue("updated"); }
        }
    }
}